package cn.edu.scau.cmi.ema.domain;


import com.alibaba.fastjson.annotation.JSONField;

import javax.persistence.*;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Set;

@Entity
@NamedQueries({ @NamedQuery(name = "findAllEvents", query = "select myEvent from Event myEvent"),
		@NamedQuery(name = "findEventByName", query = "select myEvent from Event myEvent where myEvent.name = ?1"),
		@NamedQuery(name = "findEventByNameContaining", query = "select myEvent from Event myEvent where myEvent.name like concat('%',?1,'%')"),
		@NamedQuery(name = "findEventBySourceTime", query = "select myEvent from Event myEvent where myEvent.sourceTime = ?1"),
		@NamedQuery(name = "findEventByDiscoveryTime", query = "select myEvent from Event myEvent where myEvent.discoveryTime = ?1"),
		@NamedQuery(name = "findEventByAuditTime", query = "select myEvent from Event myEvent where myEvent.auditTime = ?1"),
		@NamedQuery(name = "findEventByCrawlTime", query = "select myEvent from Event myEvent where myEvent.crawlTime = ?1"),
		@NamedQuery(name = "findEventByStatus", query = "select myEvent from Event myEvent where myEvent.status = ?1"),
		@NamedQuery(name = "findEventByDescription", query = "select myEvent from Event myEvent where myEvent.description = ?1"),
		@NamedQuery(name = "findEventByDescriptionContaining", query = "select myEvent from Event myEvent where myEvent.description like concat('%',?1,'%')"),
		@NamedQuery(name = "findAllEventsBySourceAddress", query = "select myEvent from Event myEvent where myEvent.sourceAddress.id = ?1"),
		@NamedQuery(name = "findAllEventsByDiscoveryAddress", query = "select myEvent from Event myEvent where myEvent.discoveryAddress.id = ?1"),
		@NamedQuery(name = "findAllEventsBySubject", query = "select myEvent from Event myEvent where myEvent.subject.id = ?1"),
		@NamedQuery(name = "findAllEventsByAuditor", query = "select myEvent from Event myEvent where myEvent.auditor.id = ?1"),
		@NamedQuery(name = "findAllEventsByUrl", query = "select myEvent from Event myEvent where myEvent.url.id = ?1"),
		@NamedQuery(name = "findAllEventsByReportor", query = "select myEvent from Event myEvent where myEvent.reportor.id = ?1"),
		@NamedQuery(name = "findAllEventsByParent", query = "select myEvent from Event myEvent where myEvent.parent.id = ?1"),
		@NamedQuery(name = "findAllEventsByFoodbatch", query = "select myEvent from Event myEvent where myEvent.foodbatch.id = ?1"),
		@NamedQuery(name = "findEventById", query = "select myEvent from Event myEvent where myEvent.id = ?1"),
		@NamedQuery(name = "findEventByPrimaryKey", query = "select myEvent from Event myEvent where myEvent.id = ?1 "),
		@NamedQuery(name = "deleteEventsByIds", query = "delete Event where id in (?1)"),
		@NamedQuery(name = "findEventsByIds", query = "select myEvent from Event myEvent where myEvent.id in (?1)"),
		@NamedQuery(name = "findEventIdsByParent", query = "select myEvent.id from Event myEvent where myEvent.parent.id = ?1"),
		@NamedQuery(name = "findEventByPhyscialPrimaryKey", query = "select myEvent from Event myEvent where  myEvent.subject.id = ?1 and myEvent.foodbatch.id = ?2"),
		@NamedQuery(name = "countEventsByName", query = "select count(myEvent)  from Event myEvent where myEvent.name like concat('%',?1,'%')") })
@Table(catalog = "ema", name = "event")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "ema/cn/edu/scau/cmi/ema/domain", name = "Event")
@XmlRootElement(namespace = "ema/cn/edu/scau/cmi/ema/domain")

public class Event implements Serializable, Comparable<Event> {

	private static final long serialVersionUID = 1L;

	@Column(name = "id", nullable = false)
	@Basic(fetch = FetchType.EAGER)
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@XmlElement
	Integer id;

	@Column(name = "name")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	String name;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "sourceTime")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	Calendar sourceTime;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "discoveryTime")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	Calendar discoveryTime;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "auditTime")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	Calendar auditTime;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name = "crawlTime")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	Calendar crawlTime;

	@Column(name = "status")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	Boolean status;

	@Column(name = "description")
	@Basic(fetch = FetchType.EAGER)
	@XmlElement
	String description;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "sourceAddress", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Address sourceAddress;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "discoveryAddress", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Address discoveryAddress;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "subject", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Subject subject;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "auditor", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	User auditor;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "url", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Url url;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "reportor", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	User reportor;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "parent", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Event parent;
	@JSONField(serialize = false)
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumns({ @JoinColumn(name = "foodbatch", referencedColumnName = "id", nullable = false) })
	@XmlTransient
	Foodbatch foodbatch;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "parent", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Event> eventsForParent;
	@JSONField(serialize = false)
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(catalog = "ema", name = "event2adultertype", joinColumns = {
			@JoinColumn(name = "event", referencedColumnName = "id") }, inverseJoinColumns = {
					@JoinColumn(name = "adultertype", referencedColumnName = "id") })
	@XmlElement(name = "", namespace = "")
	Set<Adultertype> adultertypesForEvent;
	@JSONField(serialize = false)
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(catalog = "ema", name = "event2discoverylink", joinColumns = {
			@JoinColumn(name = "event", referencedColumnName = "id") }, inverseJoinColumns = {
					@JoinColumn(name = "discoverylink", referencedColumnName = "id") })
	@XmlElement(name = "", namespace = "")
	Set<Discoverylink> discoverylinksForEvent;
	@JSONField(serialize = false)
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(catalog = "ema", name = "event2law", joinColumns = {
			@JoinColumn(name = "event", referencedColumnName = "id") }, inverseJoinColumns = {
					@JoinColumn(name = "law", referencedColumnName = "id") })
	@XmlElement(name = "", namespace = "")
	Set<Law> lawsForEvent;
	@JSONField(serialize = false)
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(catalog = "ema", name = "event2motive", joinColumns = {
			@JoinColumn(name = "event", referencedColumnName = "id") }, inverseJoinColumns = {
					@JoinColumn(name = "motive", referencedColumnName = "id") })
	@XmlElement(name = "", namespace = "")
	Set<Motive> motivesForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Eventadulterlink> eventadulterlinksForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Eventhazard> eventhazardsForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Eventpunish> eventpunishsForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Eventqualitytype> eventqualitytypesForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Eventquantitytype> eventquantitytypesForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Picture> picturesForEvent;
	@JSONField(serialize = false)
	@OneToMany(mappedBy = "event", cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
	@XmlElement(name = "", namespace = "")
	Set<Video> videosForEvent;

	public void setId(Integer id) {
		this.id = id;
	}

	public Integer getId() {
		return this.id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return this.name;
	}

	public void setSourceTime(Calendar sourceTime) {
		this.sourceTime = sourceTime;
	}

	public Calendar getSourceTime() {
		return this.sourceTime;
	}

	public void setDiscoveryTime(Calendar discoveryTime) {
		this.discoveryTime = discoveryTime;
	}

	public Calendar getDiscoveryTime() {
		return this.discoveryTime;
	}

	public void setAuditTime(Calendar auditTime) {
		this.auditTime = auditTime;
	}

	public Calendar getAuditTime() {
		return this.auditTime;
	}

	public void setCrawlTime(Calendar crawlTime) {
		this.crawlTime = crawlTime;
	}

	public Calendar getCrawlTime() {
		return this.crawlTime;
	}

	public void setStatus(Boolean status) {
		this.status = status;
	}

	public Boolean getStatus() {
		return this.status;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getDescription() {
		return this.description;
	}

	public void setSourceAddress(Address sourceAddress) {
		this.sourceAddress = sourceAddress;
	}

	public Address getSourceAddress() {
		return sourceAddress;
	}

	public void setDiscoveryAddress(Address discoveryAddress) {
		this.discoveryAddress = discoveryAddress;
	}

	public Address getDiscoveryAddress() {
		return discoveryAddress;
	}

	public void setSubject(Subject subject) {
		this.subject = subject;
	}

	public Subject getSubject() {
		return subject;
	}

	public void setAuditor(User auditor) {
		this.auditor = auditor;
	}

	public User getAuditor() {
		return auditor;
	}

	public void setUrl(Url url) {
		this.url = url;
	}

	public Url getUrl() {
		return url;
	}

	public void setReportor(User reportor) {
		this.reportor = reportor;
	}

	public User getReportor() {
		return reportor;
	}

	public void setParent(Event parent) {
		this.parent = parent;
	}

	public Event getParent() {
		return parent;
	}

	public void setFoodbatch(Foodbatch foodbatch) {
		this.foodbatch = foodbatch;
	}

	public Foodbatch getFoodbatch() {
		return foodbatch;
	}

	public void setEventsForParent(Set<Event> eventsForParent) {
		this.eventsForParent = eventsForParent;
	}

	public Set<Event> getEventsForParent() {
		if (eventsForParent == null) {
			eventsForParent = new java.util.LinkedHashSet<Event>();
		}
		return eventsForParent;
	}

	public void setAdultertypesForEvent(Set<Adultertype> adultertypesForEvent) {
		this.adultertypesForEvent = adultertypesForEvent;
	}

	public Set<Adultertype> getAdultertypesForEvent() {
		if (adultertypesForEvent == null) {
			adultertypesForEvent = new java.util.LinkedHashSet<Adultertype>();
		}
		return adultertypesForEvent;
	}

	public void setDiscoverylinksForEvent(Set<Discoverylink> discoverylinksForEvent) {
		this.discoverylinksForEvent = discoverylinksForEvent;
	}

	public Set<Discoverylink> getDiscoverylinksForEvent() {
		if (discoverylinksForEvent == null) {
			discoverylinksForEvent = new java.util.LinkedHashSet<Discoverylink>();
		}
		return discoverylinksForEvent;
	}

	public void setLawsForEvent(Set<Law> lawsForEvent) {
		this.lawsForEvent = lawsForEvent;
	}

	public Set<Law> getLawsForEvent() {
		if (lawsForEvent == null) {
			lawsForEvent = new java.util.LinkedHashSet<Law>();
		}
		return lawsForEvent;
	}

	public void setMotivesForEvent(Set<Motive> motivesForEvent) {
		this.motivesForEvent = motivesForEvent;
	}

	public Set<Motive> getMotivesForEvent() {
		if (motivesForEvent == null) {
			motivesForEvent = new java.util.LinkedHashSet<Motive>();
		}
		return motivesForEvent;
	}

	public void setEventadulterlinksForEvent(Set<Eventadulterlink> eventadulterlinksForEvent) {
		this.eventadulterlinksForEvent = eventadulterlinksForEvent;
	}

	public Set<Eventadulterlink> getEventadulterlinksForEvent() {
		if (eventadulterlinksForEvent == null) {
			eventadulterlinksForEvent = new java.util.LinkedHashSet<Eventadulterlink>();
		}
		return eventadulterlinksForEvent;
	}

	public void setEventhazardsForEvent(Set<Eventhazard> eventhazardsForEvent) {
		this.eventhazardsForEvent = eventhazardsForEvent;
	}

	public Set<Eventhazard> getEventhazardsForEvent() {
		if (eventhazardsForEvent == null) {
			eventhazardsForEvent = new java.util.LinkedHashSet<Eventhazard>();
		}
		return eventhazardsForEvent;
	}

	public void setEventpunishsForEvent(Set<Eventpunish> eventpunishsForEvent) {
		this.eventpunishsForEvent = eventpunishsForEvent;
	}

	public Set<Eventpunish> getEventpunishsForEvent() {
		if (eventpunishsForEvent == null) {
			eventpunishsForEvent = new java.util.LinkedHashSet<Eventpunish>();
		}
		return eventpunishsForEvent;
	}

	public void setEventqualitytypesForEvent(Set<Eventqualitytype> eventqualitytypesForEvent) {
		this.eventqualitytypesForEvent = eventqualitytypesForEvent;
	}

	public Set<Eventqualitytype> getEventqualitytypesForEvent() {
		if (eventqualitytypesForEvent == null) {
			eventqualitytypesForEvent = new java.util.LinkedHashSet<Eventqualitytype>();
		}
		return eventqualitytypesForEvent;
	}

	public void setEventquantitytypesForEvent(Set<Eventquantitytype> eventquantitytypesForEvent) {
		this.eventquantitytypesForEvent = eventquantitytypesForEvent;
	}

	public Set<Eventquantitytype> getEventquantitytypesForEvent() {
		if (eventquantitytypesForEvent == null) {
			eventquantitytypesForEvent = new java.util.LinkedHashSet<Eventquantitytype>();
		}
		return eventquantitytypesForEvent;
	}

	public void setPicturesForEvent(Set<Picture> picturesForEvent) {
		this.picturesForEvent = picturesForEvent;
	}

	public Set<Picture> getPicturesForEvent() {
		if (picturesForEvent == null) {
			picturesForEvent = new java.util.LinkedHashSet<Picture>();
		}
		return picturesForEvent;
	}

	public void setVideosForEvent(Set<Video> videosForEvent) {
		this.videosForEvent = videosForEvent;
	}

	public Set<Video> getVideosForEvent() {
		if (videosForEvent == null) {
			videosForEvent = new java.util.LinkedHashSet<Video>();
		}
		return videosForEvent;
	}

	public void copy(Event that) {

		setId(that.getId());

		setName(that.getName());
		setSourceTime(that.getSourceTime());
		setDiscoveryTime(that.getDiscoveryTime());
		setAuditTime(that.getAuditTime());
		setCrawlTime(that.getCrawlTime());
		setStatus(that.getStatus());
		setDescription(that.getDescription());

		setSourceAddress(that.getSourceAddress());

		setDiscoveryAddress(that.getDiscoveryAddress());

		setSubject(that.getSubject());

		setAuditor(that.getAuditor());

		setUrl(that.getUrl());

		setReportor(that.getReportor());

		setParent(that.getParent());

		setFoodbatch(that.getFoodbatch());

		setEventsForParent(new java.util.LinkedHashSet<Event>(that.getEventsForParent()));

		setAdultertypesForEvent(
				new java.util.LinkedHashSet<Adultertype>(that.getAdultertypesForEvent()));

		setDiscoverylinksForEvent(new java.util.LinkedHashSet<Discoverylink>(
				that.getDiscoverylinksForEvent()));

		setLawsForEvent(new java.util.LinkedHashSet<Law>(that.getLawsForEvent()));

		setMotivesForEvent(new java.util.LinkedHashSet<Motive>(that.getMotivesForEvent()));

		setEventadulterlinksForEvent(new java.util.LinkedHashSet<Eventadulterlink>(
				that.getEventadulterlinksForEvent()));

		setEventhazardsForEvent(
				new java.util.LinkedHashSet<Eventhazard>(that.getEventhazardsForEvent()));

		setEventpunishsForEvent(
				new java.util.LinkedHashSet<Eventpunish>(that.getEventpunishsForEvent()));

		setEventqualitytypesForEvent(new java.util.LinkedHashSet<Eventqualitytype>(
				that.getEventqualitytypesForEvent()));

		setEventquantitytypesForEvent(new java.util.LinkedHashSet<Eventquantitytype>(
				that.getEventquantitytypesForEvent()));

		setPicturesForEvent(
				new java.util.LinkedHashSet<Picture>(that.getPicturesForEvent()));

		setVideosForEvent(new java.util.LinkedHashSet<Video>(that.getVideosForEvent()));

	}

	public Event() {

	}

	@Override
	public String toString() {

		StringBuilder buffer = new StringBuilder();

		buffer.append("id=[").append(id).append("] ");

		buffer.append("name=[").append(name).append("] ");
		buffer.append("sourceTime=[").append(sourceTime).append("] ");
		buffer.append("discoveryTime=[").append(discoveryTime).append("] ");
		buffer.append("auditTime=[").append(auditTime).append("] ");
		buffer.append("crawlTime=[").append(crawlTime).append("] ");
		buffer.append("status=[").append(status).append("] ");
		buffer.append("description=[").append(description).append("] ");

		return buffer.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = (int) (prime * result + ((id == null) ? 0 : id.hashCode()));
		return result;
	}

	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (!(obj instanceof Event))
			return false;
		Event comparedEvent = (Event) obj;
		if (!CheckPropertyEqual(this.subject.id, comparedEvent.subject.id)) {
			return false;
		}
		if (!CheckPropertyEqual(this.foodbatch.id, comparedEvent.foodbatch.id)) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}

	@Override
	public int compareTo(Event o) {
		if (this.getId() > o.getId()) {
			return 1;
		} else if (this.getId() == o.getId()) {
			return 0;
		} else {
			return -1;
		}

	}
}
